Add protobuf serialization support for smart contract actions#32
Add protobuf serialization support for smart contract actions#32
Conversation
Introduce protocol buffer support as an alternative serialization format for contract action data, using zpp_bits for protobuf wire format encoding without linking libprotobuf in WASM. Components: - protoc-gen-zpp: custom protoc plugin generating C++ structs with zpp_bits pb_members annotations from .proto files - sysio::pb<T>: wrapper template that triggers protobuf serialization via datastream operators with varuint32 length-prefix framing - ABI generator: detects pb<T> types in action parameters, encodes them as protobuf::package.MessageType, and embeds the FileDescriptorSet schema in a protobuf_types section of the generated ABI - CMake macros: target_add_protobuf() and contract_use_protobuf() for build integration Contracts using protobuf get ABI version 1.3 (with protobuf_types); non-protobuf contracts remain at ABI version 1.2 for backward compatibility. Also updates WASM libraries to C++20 and adds zpp-bits/magic-enum vcpkg dependencies.
Point submodule to master which now includes the minimal C++20 <concepts> header needed by zpp_bits for protobuf support.
When an action has a single sysio::pb<T> parameter, the ABI now points the action type directly at the protobuf type (e.g. protobuf::pkg.Msg) instead of generating a wrapper struct. Multi-parameter actions still generate wrapper structs as before. - Add is_single_pb_param() helper in abigen.hpp - Skip wrapper struct generation for single pb<T> actions - Add multi-param pbmulti test action to pb_tests contract - Extend abi_version_tests with checks for both flattened and wrapped - Update protocol-buffers.md with single vs multi param documentation
jglanz
left a comment
There was a problem hiding this comment.
protoc, headers and zpp all need to come from vcpkg. Check comments
cmake/CDTMacros.cmake.in
Outdated
| find_program(PROTOC protoc | ||
| HINTS ${CMAKE_FIND_ROOT_PATH}/bin /usr/local/bin | ||
| REQUIRED) |
There was a problem hiding this comment.
protoc comes from the protobuf vcpkg target as a host tool (statically linked). Add it to the install config as bin/cdt-protoc
cmake/InstallCDT.cmake
Outdated
| find_program(PROTOC_PROGRAM protoc) | ||
| if(PROTOC_PROGRAM) | ||
| add_custom_command( TARGET CDTTools POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${PROTOC_PROGRAM} ${CMAKE_BINARY_DIR}/bin/ ) | ||
| install(PROGRAMS ${PROTOC_PROGRAM} | ||
| DESTINATION ${CDT_INSTALL_PREFIX}/bin) | ||
| endif() |
docs/protocol-buffers.md
Outdated
| ``` | ||
|
|
||
| The `target_add_protobuf()` function: | ||
| - Runs `protoc` with the `protoc-gen-zpp` plugin to generate `.pb.hpp` headers |
There was a problem hiding this comment.
should be changed to cdt-protoc AND protoc-gen-zpp should also be integrated into the build ideally as cdt-protoc-gen-zpp, but that would break the plugin discovery, so you may need to manually configure
jglanz
left a comment
There was a problem hiding this comment.
changes required per previous comments, i pressed the wrong button when submitting review previously
…protoc-gen-zpp - Replace find_program(protoc) with protobuf::protoc imported target from vcpkg - Rename protoc-gen-zpp → cdt-protoc-gen-zpp, install protoc as cdt-protoc - Remove /usr/local/bin fallback from CDTMacros; only search CDT install prefix - Update docs to reflect renamed tool names
| add_custom_command( | ||
| COMMENT "Generating ${OUTPUT_HDRS} from ${INPUT_FILES}" | ||
| OUTPUT ${OUTPUT_HDRS} | ||
| COMMAND ${PROTOC} -I ${ADD_PROTOBUF_INPUT_DIRECTORY} -I ${CMAKE_FIND_ROOT_PATH}/include --plugin=protoc-gen-zpp=${CMAKE_FIND_ROOT_PATH}/bin/cdt-protoc-gen-zpp --zpp_out ${OUTPUT_DIR} ${ADD_PROTOBUF_FILES} |
jglanz
left a comment
There was a problem hiding this comment.
Great work - thanks for the refactor, we are starting to look like pros!
…ct_use_protobuf contract_use_protobuf propagated include directories and compile options but had no build ordering dependency on the protobuf generation target. In parallel CI builds, the contract compiled before the .pb.hpp file was generated, causing a fatal "file not found" error.
Remove explicit template arguments from deleted copy constructor and assignment operator declarations inside class templates. GCC 13 in C++23 mode rejects the ClassName<T>(...) syntax in this context.
Summary
Introduces Protocol Buffer support as an alternative serialization format for smart contract action data. Contracts can now use protobuf's binary wire format instead of standard CDT datastream packing by wrapping action parameters in
sysio::pb<T>.Uses zpp_bits for protobuf wire format encoding — a header-only C++20 library that works in WASM without exceptions or linking libprotobuf.
See new
docs/protocol-buffers.mdfor more info.Components
protoc-gen-zpp— Custom protoc plugin that generates C++ structs withzpp_bitsprotobuf annotations from.protofilessysio::pb<T>— Wrapper template that triggers protobuf serialization via datastream operators with varuint32 length-prefix framingpb<T>types in action parameters, encodes them asprotobuf::package.MessageType, and embeds theFileDescriptorSetschema in aprotobuf_typessection of the generatedABI
target_add_protobuf()andcontract_use_protobuf()for build integrationABI Versioning
protobuf_typessectionOther Changes
zpp-bitsandmagic-enumvcpkg dependencies<concepts>header (pending cdt-libcxx PR#2)Documentation
See docs/protocol-buffers.md for usage guide.